/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package login;

import javax.jws.WebService;
import javax.jws.WebMethod;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.Writer;

@WebService()
public class userDBDriver {

    /**
     * Global variable for transferring data between methods
     */
    String[] FILEARRAY;

//    Test method below (to be used in eclipse):
//    public static void main(String[] args) {
//        int success1 = createCategoryDB("action");
//        System.out.println(success1);
//        int success2 = createCategoryDB("drama");
//        System.out.println(success2);
//        int success3 = createCategoryDB("comedy");
//        System.out.println(success3);
//
//        int success4 = databaseConnect("action");
//        System.out.println(success4);
//        String success5 = addBook("12345", "Spiderman", "Hello!", "1.99");
//        System.out.println(success5);
//        String success6 = addBook("54321", "The Hulk", "Green", "4.99");
//        System.out.println(success6);
//
//        String[] all1 = getAllBooks();
//        for(int i=0; i<all1.length; i++){
//            System.out.println(all1[i]);
//        }
//
//        int success7 = databaseConnect("drama");
//        System.out.println(success7);
//        String success8 = addBook("00000", "Wuthering Heights", "Haworth", "2.99");
//        System.out.println(success8);
//        String success9 = addBook("11111", "Of Mice and Men", "America", "0.99");
//        System.out.println(success9);
//
//        String[] all2 = getAllBooks();
//        for(int i=0; i<all2.length; i++){
//            System.out.println(all2[i]);
//        }
//    }

    // CREATE DIRECTORY
    /**
     * Method called to create a sub-directory at the current directory of name
     * 'dirname'
     *
     * @param dirname
     *            Name of directory to be created
     * @return 0 for successful completion; -1 for failure
     */
    private int createDir(String dirname) {
        try {
            boolean success = (new File(dirname).mkdirs());
            if (success) {
                return 0;
            } else {
                return -1;
            }
        } catch (Exception e) {
            return -1;
        }
    }

    // DELETE DIRECTORY
    /**
     * Method called to delete a sub-directory at the current directory of name
     * 'dirname'
     *
     * @param dirname
     *            Name of directory to be deleted
     * @return 0 for successful completion; -1 for failure
     */
    private int deleteDir(String dirname) {
        try {
            boolean success = (new File(dirname).delete());
            if (success) {
                return 0;
            } else {
                return -1;
            }
        } catch (Exception e) {
            return -1;
        }
    }

    // CREATE FILE
    /**
     * Method called to create a text file named by 'filename' in the directory
     * given by 'dirname'
     *
     * @param filename
     *            Name of file to be created
     * @param dirname
     *            Name of directory where file is to be created
     * @return 0 for successful completion; -1 for failure
     */
    private int createFile(String filename, String dirname) {
        try {
            createDir(dirname);
            File f = new File(dirname, filename + ".txt");
            if (!f.exists()) {
                f.createNewFile();
                return 0;
            } else {
                return -1;
            }
        } catch (Exception e) {
            return -1;
        }
    }

    // DELETE FILE
    /**
     * Method called to delete a text file named by 'filename' in the directory
     * given by 'dirname'
     *
     * @param filename
     *            Name of file to be deleted
     * @param dirname
     *            Name of directory to be deleted
     * @return 0 for successful completion; -1 for failure
     */
    private int deleteFile(String filename, String dirname) {
        try {
            File f = new File(dirname, filename + ".txt");
            if (f.exists()) {
                f.delete();
                deleteDir(dirname);
                return 0;
            } else {
                return -1;
            }
        } catch (Exception e) {
            return -1;
        }
    }

    // WRITE TO FILE
    /**
     * Method called to append data to a given file of 'filename'.txt
     *
     * @param data
     *            Data to be written
     * @param filename
     *            Name of file to be written to
     * @param dirname
     *            Name of directory file to be written to is in
     * @return 0 for successful completion; -1 for failure
     */
    private int writeToFile(String data, String filename, String dirname) {
        try {
            createFile(filename, dirname);
            Writer output = new BufferedWriter(new FileWriter("./" + dirname
                    + "/" + filename + ".txt", true));
            output.write(data + "\n");
            output.close();
            return 0;
        } catch (Exception e) {
            return -1;
        }
    }

    // READ FROM FILE
    /**
     * Method called to read data from a file given a unique ID
     *
     * @param uniqueID
     *            Term to search for
     * @param filename
     *            Name of file to read from
     * @param dirname
     *            Name of directory file to be read is in
     * @return 0 for successful completion; -1 for failure
     */
     private int readFromFile(String uniqueID, String filename, String dirname) {
        try {
            FileInputStream fstream = new FileInputStream("./" + dirname + "/"
                    + filename + ".txt");
            DataInputStream in = new DataInputStream(fstream);
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String strLine;
            int i = 0;
            String[] fileArray = new String[0];
            while ((strLine = br.readLine()) != null) {
                if (strLine.contains(uniqueID) == true
                        || uniqueID.equals("printAll")) {
                    String[] newFileArray = new String[fileArray.length + 1];
                    int j = 0;
                    while (j < fileArray.length) {
                        newFileArray[j] = fileArray[j];
                        j++;
                    }
                    newFileArray[i] = strLine;
                    fileArray = newFileArray;
                    i++;
                }
            }
            FILEARRAY = new String[fileArray.length];
            int j = 0;
            while (j < FILEARRAY.length) {
                FILEARRAY[j] = fileArray[j];
                j++;
            }
            in.close();
            return 0;
        } catch (Exception e) {
            return -1;
        }
    }

    /****************************************************************************************************************************/
    /** Declare global variables: */
    String SERVICENAME = "bookDatabase";
    String CATEGORY = null;
    Boolean CLIENTCONNECTED = false;

    // CREATE CATEGORY
    /**
     * This method is called to set up a database on the service. This must be
     * called else the service will not connect as it has no database to store
     * data on.
     *
     * Method returns 0 if the client database is created for the first time and
     * -1 if there is already a client database that matches category on the
     * service.
     *
     * @param category
     *            Unique ID of the client
     * @return 0 for successful completion; -1 for failure
     */
    @WebMethod(operationName = "createCategoryDB")
    public int createCategoryDB(String category) {
        try {
            int success = createFile(category  + "Database", SERVICENAME);
            if (success == 0) {
                return 0;
            } else {
                return -1;
            }
        } catch (Exception e) {
            return -1;
        }
    }

    // CONNECT CATEGORY
    /**
     * This method must be called whenever the client connects to the service.
     * This method is used to connect to the database that corresponds with the
     * clientâ€™s category.
     *
     * ClientID must be the same whenever the client connects to the service
     * otherwise the database will not be found.
     *
     * Method returns 0 on success and -1 on error. If -1 is returned then
     * either the category is wrong or the client has not created a database,
     * call createClientDB() if this is the case.
     *
     * @param category
     *            Unique ID of the client
     * @return 0 for successful completion; -1 for failure
     */
    @WebMethod(operationName = "databaseConnect")
    public int databaseConnect(String category) {
        try {
            int success = createFile(category  + "Database", SERVICENAME);
            if (success != 0) {
                CATEGORY = category  + "Database";
                CLIENTCONNECTED = true;
                return 0;
            } else {
                deleteFile(category  + "Database", SERVICENAME + category);
                return -1;
            }
        } catch (Exception e) {
            return -1;
        }
    }

    /****************************************************************************************************************************/
    // Add a book to the database
    /**
     * This method is used to add a book to the database
     *
     * â€œBook savedâ€ is returned on success. â€œBook not savedâ€ if there is
     * a problem connecting to the database. â€œClient not connectedâ€ is returned
     * if databaseConnect() has not been called upon connecting to the server.
     *
     * @param ISBN
     *            Unique identifier
     * @param title
     *            Title of the book
     * @param description
     *            Description of the book
     * @param price
     *            Current price of the book
     * @return String containing "Book saved" for success;
     *         "Book not saved" or "Client not connected" on failure
     */
    @WebMethod(operationName = "addUser")
    public String addUser(String username, String realname, String email, String password) {
        if (CLIENTCONNECTED == true) {
            //check exists



            String data = username + "\t" + realname + "\t" + email + "\t" + password;
            int successful = writeToFile(data, CATEGORY, SERVICENAME);

            if (successful == 0) {
                /** Return confirmation message */
                return "User saved";
            } else {
                /** Return error message */
                return "User not saved";
            }
        } else {
            /** Return error message */
            return "Client not connected";
        }
    }

    // Return all books in file
    /**
     * When this method is called it returns a String array of all the records
     * stored on the database. A record is in the form â€œuserID,
     * itemID,feedbackStringâ€. On fail it returns a string array with only one
     * string in it. If databaseConnect() was not run then this string will read
     * â€œClient not connectedâ€ else if the file was not read then the string will
     * read â€œFile not readâ€.
     *
     * @return An array, where each block contains a feedback article; returns
     *         String[0] as either "File not read" or "Client not connected" on
     *         failure
     */
    @WebMethod(operationName = "getAllUsers")
    public String[] getAllUsers() {
        if (CLIENTCONNECTED == true) {
            int successful = readFromFile("printAll", CATEGORY,
                    SERVICENAME);
            if (successful == 0) {
                return FILEARRAY;
            } else {
                /** Return error message */
                String[] error1 = new String[1];
                error1[0] = "File not read";
                return error1;
            }
        } else {
            /** Return error message */
            String[] error2 = new String[1];
            error2[0] = "Client not connected";
            return error2;
        }
    }

    // Search for a book with the given ISBN
    // If record does not exist then null will be returned
    /**
     * When this method is called it returns a String array of all the books
     * stored on the database that match the search parameter â€œISBNâ€.
     * On fail it returns a string array with only one string in it.
     * If databaseConnect() was not run then this string will read â€œClient not
     * connectedâ€ else if the file was not read then the string will read
     * â€œFile not readâ€.
     *
     * @param ISBN
     *            Unique ID to specify the book being looked for
     * @return An array, where each block contains a book article; returns
     *         String[0] as either "File not read" or "Client not connected" on
     *         failure
     */
    @WebMethod(operationName = "getUser")
    public String[] getUser(String username) {
        if (CLIENTCONNECTED == true) {
            int successful = readFromFile(username, CATEGORY,
                    SERVICENAME);
            if (successful == 0) {
                return FILEARRAY;
            } else {
                /** Return error message */
                String[] error1 = new String[1];
                error1[0] = "File not read";
                return error1;
            }
        } else {
            /** Return error message */
            String[] error2 = new String[1];
            error2[0] = "Client not connected";
            return error2;
        }
    }

    // Check if user already exists
    /**
     * This method is used to check if a given username already exists
     *
     *
     * @param username
     *              Checking if this user exists
     * @return boolean
     *          True if this person exists, false if doesnt.
      *
     */
    @WebMethod(operationName = "checkExists")
    public boolean checkExists(String inputusername) {
        boolean found = false;
        String[] resultsArray = getAllUsers();
        for (int i = 0; i < resultsArray.length; i++)
        {
            if(resultsArray[i].contains(inputusername))
            {
                found = true;
            }
        }
        if(found == true){return true;}
        else {return false;}
     }

    // Check inputs are valid
    /**
     * This method is used to check if the given registration details are valid

     * @return string
     *          String has appropriate error message of "none" if successful
      *

    @WebMethod(operationName = "validateInputs")
    public String validateInputs(String inputusername, String inputemail, String inputrealname, String inputpassword, String inputpasswordconfirm ) {
        String errormessage = "none";
        try{
            if(inputusername.equals("") || inputemail.equals("") || inputrealname.equals("") || inputpassword.equals("") || inputpasswordconfirm.equals("") || inputusername == null || inputemail == null || inputrealname == null || inputpassword == null || inputpasswordconfirm == null)
            {
                errormessage = "Cant be blank.";
            }
              }
        catch (NullPointerException e)
        {
             errormessage = "null pointer1";
        }
        try{
               if(checkExists(inputusername) == true)
                {
                    // errormessage = "Username already exists.";
                }
        }
         catch (NullPointerException e)
        {
             errormessage = "null pointer2";
        }
        try{
                    if( ! inputpassword.equals(inputpasswordconfirm))
                    {
                        // errormessage = "Passwords must match.";
                    }
        }
                catch (NullPointerException e)
        {
             errormessage = "null pointer3";
        }

            return errormessage;
     }
        */
}